#include "auth.h"

#include <stdlib.h>

bool auth_init(auth_ptr *l){
	*l = (auth_ptr)malloc(sizeof(auth));
	if((*l) != NULL){
		(*l)->next = NULL;
		(*l)->sock = -1;
		(*l)->port = -1;
		strcpy((*l)->uname, "notuse");
		strcpy((*l)->ipv4, "@");
		strcpy((*l)->curpath, "/");

		if(DEBUG){
			printf("auth_init() size: %d \n", auth_size(*l));
			printf("auth_init() addr: %p \n", *l);
		}
		return true;
	}

	return false;
}

void auth_destroy(auth_ptr *l){
	auth_ptr p=*l,q=p->next;

	while(q != NULL){
		if(DEBUG){
			printf("Auth Socket: %p => %d \n", q, q->sock);
		}
		p->next = q->next;
		if(q->sock != -1){
			if(DEBUG){
				printf("close client socket %d. \n", q->sock);
			}
			close(q->sock);
		}
		free(q);
		q = p->next;
	}

	free(*l);
	*l = NULL;
}

bool auth_empty(auth_ptr l){
	return (l->next == NULL) ? true : false;
}

void auth_push(auth_ptr l, auth_ptr node){
	auth_ptr temp = (auth_ptr)malloc(sizeof(auth));

	if(DEBUG){
		printf("auth_push new point addr: %p \n", temp);
	}
	temp->auth = node->auth;
	temp->sock = node->sock;
	strcpy(temp->ipv4, node->ipv4);
	temp->port = node->port;
	strcpy(temp->uname, node->uname);
	strcpy(temp->curpath, node->curpath);

	temp->next = l->next;
	l->next = temp;
}

auth auth_pop(auth_ptr l){
	auth_ptr p = l->next;

	l->next = p->next;

	return *p;
}

int auth_size(auth_ptr l){
	auth_ptr p = l->next;
	register int len=0;

	while(p != NULL){
		len++;
		p = p->next;
	}

	return len;
}

void auth_traverse(auth_ptr l,void (*funcp)(auth_ptr)){
	auth_ptr p=l->next;

	while(p != NULL){
		funcp(p);
		p = p->next;
	}
}

void auth_reverse(auth_ptr l){
	auth_ptr cur,prev,p=l,temp;
	int i,len;

	len = auth_size(l);

	for(i=0;i<len;i++){
		for(prev=l,cur=l->next; cur != NULL; prev=cur,cur=cur->next)
			;
		prev->next = NULL;
		temp = p->next;
		p->next = cur;
		cur->next = temp;
		p = cur;
	}
}

auth_ptr auth_find(auth_ptr l, int clnt_sock){
	auth_ptr p=l->next;

	while(p != NULL){
		if(p->sock == clnt_sock){
			return p;
		}
		p = p->next;
	}

	return NULL;
}

bool auth_contains(auth_ptr l, int clnt_sock){
	return (auth_find(l, clnt_sock) != NULL);
}

bool auth_remove(auth_ptr l, int clnt_sock){
	auth_ptr prev=NULL,cur=NULL,rsp=auth_find(l, clnt_sock);

	if(DEBUG){
		printf("before auth_remove() size: %d \n", auth_size(l));
		printf("find point to be removed addr: %p \n", rsp);
		auth_traverse(auth_list, print_l);
	}

	if(rsp != NULL){//从第二个节点开始找起
		for(prev=l,cur=l->next; cur != NULL && cur != rsp; prev=cur,cur=cur->next)
			;

		if(cur == NULL){
			return true;
		}else{
			prev->next = cur->next;
			free(cur);
		}

		if(DEBUG){
			printf("find current point addr: %p \n", cur);
			printf("after auth_remove() size: %d \n", auth_size(l));
		}
		return true;
	}

	return false;
}

void print_l(auth_ptr p){
	printf("UserName: %-*s\tSocket: %-2d\nIPv4 Address: %-*s\tPort: %-*d \
			\nAuth Status: %d\tPriv: %-*s\nCurrent Path: %-*s\n",
			UNAME_LEN, p->uname, p->sock, IPV4_LEN, p->ipv4, PORT_LEN, p->port,
			p->auth, PRIV_CMD_LEN, p->priv, PATH_LEN, p->curpath);
	fputc('\n', stdout);
}
